package newkfp;

import Beans.AddedItem;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpSession;
import newkfp.util.JsfUtil;
import newkfp.util.PaginationHelper;
import pojos.Treausry;

@ManagedBean(name = "billConfirmController")
@SessionScoped
public class BillConfirmController implements Serializable {

    @ManagedProperty(value = "#{itemController}")
    ItemController itemController;
    @EJB
    private newkfp.TreausryFacade treausryFacade;
    @EJB
    private newkfp.CustomerFacade customerFacad;
    @EJB
    private newkfp.ExporterFacade exporterFacade;
    @EJB
    private newkfp.ItemFacade itemFacad;
    Loger loger;
    @EJB
    private newkfp.LogFacade logFacade;
    private Double total = 0.0, cach = 0.0, remin = 0.0;
    private int type;
    private Bill current;
    private String title = "فواتير العملاء";
    private DataModel items = null;
    @EJB
    private newkfp.BillFacade ejbFacade;
    @EJB
    private BillItemFacade billItemFacade;
    @EJB
    private newkfp.BillFacade billFacade;
    private PaginationHelper pagination;
    private int selectedItemIndex;
    @ManagedProperty(value = "#{billInformationController}")
    BillInformation billInformation;
    @ManagedProperty(value = "#{billExporterInformationController}")
    BillExporterInformation billExporterInformation;
    private boolean selected;
    private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();

    public BillConfirmController() {
        loger = new Loger(getLogFacade());
    }

    public Bill getSelected() {
        if (current == null) {
            current = new Bill();
            selectedItemIndex = -1;
        }
        return current;
    }

    private BillFacade getFacade() {
        return ejbFacade;
    }

    public PaginationHelper getPagination() {
        if (pagination == null) {
            pagination = new PaginationHelper(getFacade().count()) {
                @Override
                public int getItemsCount() {
                    return getFacade().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    if (type == 1) {
                        System.out.println("getNotConfirmedExporterBill");

                        return new ListDataModel(getFacade().getNotConfirmedExporterBill());
                    } else {
                        System.out.println("getNotConfirmedCusromerBill");
                        return new ListDataModel(getFacade().getNotConfirmedCusromerBill());
                    }

                }
            };
        }
        getBillTotalCach();
        return pagination;
    }

    public String prepareList() {
        recreateModel();
        return "List";
    }

    public String prepareView() {
        current = (Bill) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "View";
    }

    public String prepareCreate() {
        current = new Bill();
        selectedItemIndex = -1;
        return "Create";
    }

    public String create() {
        try {
            getFacade().create(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("BillCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String prepareEdit() {
        current = (Bill) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "Confirm";
    }

    public String confirm(Bill bill) {
        billInformation.setBillNumber(bill.getBillNumber());
        billInformation.setCustomerName(bill.getCustomerID().getCustomerName());

        billInformation.setSelectedCustomer(bill.getCustomerID());
        billInformation.setBillTotal(bill.getBillTotal());
        billInformation.setPaied(bill.getBillCach());
        billInformation.setBill_reminder(bill.getBillReminder());
//        System.out.println("bill.getBillItemCollection() : " + bill.getBillItemCollection().size());

        billInformation.setAdd_Item(createAddedItemList(getBillItemFacade().getItemsByBillId(bill.getIdBill())));
        billInformation.setBill(bill);
        billInformation.setBillDate(bill.getCreateDate());
        return "Confirm";
    }

    public String exporterConfirm(Bill bill) {

        billExporterInformation.setBillNumber(bill.getBillNumber());
        billExporterInformation.setExporterName(bill.getExporterID().getExporterName());
        billExporterInformation.setDocNumber(bill.getDocNum());
        billExporterInformation.setSelectedExporter(bill.getExporterID());
        billExporterInformation.setBillTotal(bill.getBillTotal());
        billExporterInformation.setPaied(bill.getBillCach());
        billExporterInformation.setBill_reminder(bill.getBillReminder());
        billExporterInformation.setAdd_Item(createAddedItemList(getBillItemFacade().getItemsByBillId(bill.getIdBill())));
        billExporterInformation.setBill(bill);
        billExporterInformation.setBillDate(bill.getCreateDate());
        return "ExporterConfirm";
    }

    public String update() {
        try {
            getFacade().edit(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("BillUpdated"));
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String destroy() {
        current = (Bill) getItems().getRowData();
        System.out.println("Selected Bill: " + current.getBillNumber());
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        performDestroy();
        recreateModel();
        return "confirmBills";
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        updateCurrentItem();
        if (selectedItemIndex >= 0) {
            return "View";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "List";
        }
    }

    private void performDestroy() {
        try {
            getFacade().remove(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("BillDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }

    private void updateCurrentItem() {
        int count = getFacade().count();
        if (selectedItemIndex >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndex = count - 1;
            // go to previous page if last page disappeared:
            if (pagination.getPageFirstItem() >= count) {
                pagination.previousPage();
            }
        }
        if (selectedItemIndex >= 0) {
            current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
        }
    }

    public DataModel getItems() {
        if (items == null) {
            items = getPagination().createPageDataModel();
        }
        return items;
    }

    private void recreateModel() {
        items = null;
    }

    public String next() {
        getPagination().nextPage();
        recreateModel();
        return "List";
    }

    public String previous() {
        getPagination().previousPage();
        recreateModel();
        return "List";
    }

    public SelectItem[] getItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
    }

    /**
     * @return the type
     */
    public int getType() {
        return type;
    }

    /**
     * @param type the type to set
     */
    public void setType(int type) {
        this.type = type;
    }

    /**
     * @return the title
     */
    public String getTitle() {
        return title;
    }

    /**
     * @param title the title to set
     */
    public void setTitle(String title) {
        this.title = title;
    }

    @FacesConverter(forClass = Bill.class)
    public static class BillControllerConverter implements Converter {

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            BillConfirmController controller = (BillConfirmController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "billController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Integer value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Bill) {
                Bill o = (Bill) object;
                return getStringKey(o.getIdBill());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + BillConfirmController.class.getName());
            }
        }
    }

    public String exporter() {
        type = 1;
        getPagination();
        recreateModel();
        setTitle("فواتير الموردين");
        return "confirmBills";
    }

    public String customer() {
        type = 0;
        getPagination();
        setTitle("فواتير العملاء");
        recreateModel();
        return "confirmBills";
    }

    public BillInformation getBillInformation() {
        return billInformation;
    }

    public void setBillInformation(BillInformation billInformation) {
        this.billInformation = billInformation;
    }

    private ArrayList<AddedItem> createAddedItemList(Collection<BillItem> billItems) {
        ArrayList<AddedItem> addedItems = new ArrayList<AddedItem>();
        for (BillItem billItem : billItems) {
            if (billItem.getExportBill() == 0) {
                addedItems.add(new AddedItem(billItem.getFactoryID().getIdcountry().getCountryName(), billItem.getFactoryID().getFactoryName(), billItem.getItemID().getItemName(), billItem.getItemPrice(), billItem.getTotalPrice(), billItem.getPackageCount(), billItem.getItemAmount(), null, false, billItem.getBillItemStatus()));
            } else {
                addedItems.add(new AddedItem(billItem.getFactoryID().getIdcountry().getCountryName(), billItem.getFactoryID().getFactoryName(), billItem.getItemID().getItemName(), billItem.getItemPrice(), billItem.getTotalPrice(), billItem.getPackageCount(), billItem.getItemAmount(), null, true, billItem.getBillItemStatus()));
            }

        }
        return addedItems;
    }

    public BillExporterInformation getBillExporterInformation() {
        return billExporterInformation;
    }

    public void setBillExporterInformation(BillExporterInformation billExporterInformation) {
        this.billExporterInformation = billExporterInformation;
    }

    public BillItemFacade getBillItemFacade() {
        return billItemFacade;
    }

    public void setBillItemFacade(BillItemFacade billItemFacade) {
        this.billItemFacade = billItemFacade;
    }

    public void getBillTotalCach() {

        List list;
        if (type == 1) {
            list = getFacade().getNotConfirmedExporterBill();
        } else {
            list = getFacade().getNotConfirmedCusromerBill();
        }
        total = 0.0;
        remin = 0.0;
        cach = 0.0;
        for (Iterator it = list.iterator(); it.hasNext();) {
            Bill bill = (Bill) it.next();
            total += bill.getBillTotal();
            remin += bill.getBillReminder();
            cach += bill.getBillCach();
        }


    }

    public Double getCach() {
        return cach;
    }

    public void setCach(Double cach) {
        this.cach = cach;
    }

    public Double getRemin() {
        return remin;
    }

    public void setRemin(Double remin) {
        this.remin = remin;
    }

    public Double getTotal() {
        return total;
    }

    public void setTotal(Double total) {
        this.total = total;
    }

    public LogFacade getLogFacade() {
        return logFacade;
    }

    public void setLogFacade(LogFacade logFacade) {
        this.logFacade = logFacade;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public Map<Long, Boolean> getChecked() {
        return checked;
    }

    public void setChecked(Map<Long, Boolean> checked) {
        this.checked = checked;
    }

    public String confirmSelected() {
        try {
            Iterator<Bill> itr = items.iterator();
            while (itr.hasNext()) {
                Bill bill = itr.next();
                if (checked.get(bill.getIdBill())) {
                    Iterator iterator = billFacade.getBillItems(bill.getIdBill()).iterator();
                    for (Iterator it = iterator; it.hasNext();) {
                        BillItem billitem = (BillItem) it.next();
                        Item item = billitem.getItemID();

                        if (billitem.getBillItemStatus().equalsIgnoreCase("WithoutValue") || billitem.getBillItemStatus().equalsIgnoreCase("ProductExecution")) {
                            // updating Item number of packages  
                            item.setPk_Count(item.getPk_Count());
                            // updating item quantity
                            item.setQuantity(item.getQuantity());
                            //adjusting customer balance
                        }
                        if (billitem.getBillItemStatus().equalsIgnoreCase("SalesReturn")) {
                            // updating Item number of packages 
                            item.setPk_Count(item.getPk_Count() + billitem.getPackageCount());
                            // updating item quantity
                            item.setQuantity(item.getQuantity() + billitem.getItemAmount());
                            //adjusting customer balance
                        }
                        if (billitem.getBillItemStatus().equalsIgnoreCase("Regular") || billitem.getBillItemStatus().equalsIgnoreCase("") || billitem.getBillItemStatus() == null) {
                            // updating Item number of packages 
                            item.setPk_Count(item.getPk_Count() - billitem.getPackageCount());
                            // updating item quantity
                            item.setQuantity(item.getQuantity() - billitem.getItemAmount());
                        }
                        itemFacad.edit(item);
                    }

                    bill.setTempFlag(0);
                    getBillFacade().edit(bill);

                    Customer selectedCustomer = bill.getCustomerID();
                    selectedCustomer.setBalance(bill.getBillReminder() + selectedCustomer.getBalance());
                    customerFacad.edit(selectedCustomer);

                    String s = "تم تاكيد فاتوره رقم ";
                    String sd = "دفتر رقم ";
                    String ss = "  للعميل رقم :";
                    String t = "باجمالي : ";
                    String d = "في تاريخ";
                    loger.LogerString(s + bill.getBillNumber() + sd + bill.getDocNum() + ss + selectedCustomer.getCustomerName() + "  " + d + " " + getCDate(bill) + " " + t + bill.getBillTotal(), 0);


                    HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
                    Treausry treausry = new Treausry();
                    treausry.setActionDate(bill.getCreateDate());
                    treausry.setCustomerId(selectedCustomer);
                    treausry.setEmployeeId(new Employee(Integer.parseInt(session.getValue("empid").toString())));
                    treausry.setExporterId(null);
                    treausry.setGeneralDescription(s + bill.getBillNumber() + sd + bill.getDocNum() + ss + selectedCustomer.getCustomerName());
                    treausry.setMoneyAmount(bill.getBillCach());
                    treausry.setBillId(bill);
                    treausryFacade.create(treausry);
                }
            }
            checked.clear();
            JsfUtil.addSuccessMessage("تم التاكيد");
            recreateModel();
            return "confirmBills";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("DeleteError"));
            return null;
        }
    }

    public String exporterConfirmSelected(){
        try{
            Iterator<Bill> itr = items.iterator();
            while (itr.hasNext()) {
                Bill bill = itr.next();
                if (checked.get(bill.getIdBill())) {
                    System.out.println("bill.getBillItemCollection():" + billFacade.getBillItems(bill.getIdBill()).size());
                    Iterator iterator = billFacade.getBillItems(bill.getIdBill()).iterator();
                    for (Iterator it = iterator; it.hasNext();) {
                        BillItem billitem = (BillItem) it.next();
                        Item item = billitem.getItemID();

                        if (billitem.getBillItemStatus().equalsIgnoreCase("ProductExecution")) {
                            // updating Item number of packages  
                            item.setPk_Count(item.getPk_Count());
                            // updating item quantity
                            item.setQuantity(item.getQuantity());
                            //adjusting customer balance
                        }
                        if (billitem.getBillItemStatus().equalsIgnoreCase("Regular") || billitem.getBillItemStatus().equalsIgnoreCase("") || billitem.getBillItemStatus() == null) {
                            // updating Item number of packages 
                            item.setPk_Count(item.getPk_Count() + billitem.getPackageCount());
                            // updating item quantity
                            item.setQuantity(item.getQuantity() + billitem.getItemAmount());
                        }
                        itemFacad.edit(item);
                    }
                    
                    bill.setTempFlag(0);
                    getBillFacade().edit(bill);

                    Exporter selectedExporter = bill.getExporterID();
                    selectedExporter.setBalance(bill.getBillReminder() + selectedExporter.getBalance());
                    exporterFacade.edit(selectedExporter);

                    String s = "تم تاكيد فاتوره رقم ";
                    String sd = "دفتر رقم ";
                    String ss = "  للمورد :";
                    String t = "باجمالي : ";
                    String d = "في تاريخ";
                    loger.LogerString(s + bill.getBillNumber() + sd + bill.getDocNum() + ss + selectedExporter.getExporterName() + "  " + d + " " + getCDate(bill) + " " + t + bill.getBillTotal(), 0);

                    Treausry treausry = new Treausry();
                    treausry.setActionDate(bill.getCreateDate());
                    treausry.setCustomerId(null);
                    HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
                    treausry.setEmployeeId(new Employee(Integer.parseInt(session.getValue("empid").toString())));
                    treausry.setExporterId(selectedExporter);
                    treausry.setGeneralDescription(s + bill.getBillNumber() + sd + bill.getDocNum() + ss + selectedExporter.getExporterName());
                    treausry.setMoneyAmount(-1 * bill.getBillCach());
                    treausry.setBillId(bill);
                    treausryFacade.create(treausry);
                }
            }
            itemController.prepare();
            checked.clear();
            JsfUtil.addSuccessMessage("تم التاكيد");
            recreateModel();
            return "confirmBills";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("DeleteError"));
            return null;
        }
    }

    public BillFacade getBillFacade() {
        return billFacade;
    }

    public void setBillFacade(BillFacade billFacade) {
        this.billFacade = billFacade;
    }

    public ItemFacade getItemFacad() {
        return itemFacad;
    }

    public void setItemFacad(ItemFacade itemFacad) {
        this.itemFacad = itemFacad;
    }

    public CustomerFacade getCustomerFacad() {
        return customerFacad;
    }

    public void setCustomerFacad(CustomerFacade customerFacad) {
        this.customerFacad = customerFacad;
    }

    public TreausryFacade getTreausryFacade() {
        return treausryFacade;
    }

    public void setTreausryFacade(TreausryFacade treausryFacade) {
        this.treausryFacade = treausryFacade;
    }

    public String getCDate(Bill b) {
        String CDate;
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
        CDate = dateFormat.format(b.getCreateDate());
        return CDate;
    }

    public ExporterFacade getExporterFacade() {
        return exporterFacade;
    }

    public void setExporterFacade(ExporterFacade exporterFacade) {
        this.exporterFacade = exporterFacade;
    }

    public ItemController getItemController() {
        return itemController;
    }

    public void setItemController(ItemController itemController) {
        this.itemController = itemController;
    }
}
